#!/bin/sh

#    This file is part of P4wnP1.
#
#    Copyright (c) 2017, Marcus Mengs. 
#
#    P4wnP1 is free software: you can redistribute it and/or modify
#    it under the terms of the GNU General Public License as published by
#    the Free Software Foundation, either version 3 of the License, or
#    (at your option) any later version.
#
#    P4wnP1 is distributed in the hope that it will be useful,
#    but WITHOUT ANY WARRANTY; without even the implied warranty of
#    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
#    GNU General Public License for more details.
#
#    You should have received a copy of the GNU General Public License
#    along with P4wnP1.  If not, see <http://www.gnu.org/licenses/>.

#
# P4wnP1 startup script
# 	Author:	Marcus Mengs (MaMe82)
#
# Notes:
#	- work in progress (contains possible errors and typos)
#	- if the device isn't detected changing the USB port (USB 2.0 prefered) or plug out and in
#	  again could help
#
# ToDo:
#	- add manual system date adjusment, to not mess up logs due to missing NTP (store datetime of last boot)
#	- add shutdown capability to script, to allow file system syncing before power loss (could be done from 
#	payload by calling "sync && sudo halt")


# find working dir of script
wdir=$( cd $(dirname $BASH_SOURCE[0]) && cd .. && pwd)

echo =================================== P4wnP1 startup ===========================================
echo "P4wnP1: Init LED control..."
source $wdir/boot/init_led.sh

echo "P4wnP1: Loading config ..."
source $wdir/boot/init_config.sh

# Create bash script which could be altered from /home/pi/.profile
touch /tmp/profile.sh
echo "#!/bin/bash" >> /tmp/profile.sh
echo "wdir=$wdir" >> /tmp/profile.sh
echo "lang=$lang" >> /tmp/profile.sh
echo $(declare -p ledtrigger | cut -d" " -f3) >> /tmp/profile.sh
declare -f led_blink >> /tmp/profile.sh
declare -f onLogin >> /tmp/profile.sh
chown pi:pi /tmp/profile.sh

echo "P4wnP1: Initializing USB gadget ..."
source $wdir/boot/init_usb.sh
init_usb

echo "P4wnP1: Checking for WiFi capabilities ..."
source $wdir/boot/init_wifi.sh
check_wifi
if $WIFI; then
	echo "P4wnP1: Seems WiFi module is present !"
	iw reg set $WIFI_REG

	source $wdir/boot/init_wifi_nexmon.sh
	if $WIFI_NEXMON; then
		# swap firmware and driver
		WIFI_activate_nexmon

	fi


	# start WIFI client
	if $WIFI_CLIENT; then
		# try to connect to existing WiFi according to the config
		sleep 1 # pause to make new reg domain accessible in scan
		if start_wifi_client; then
			WIFI_CLIENT_CONNECTION_SUCCESS=true
		else
			echo "P4wnP1: Join present WiFi didn't succeed, failing over to access point mode"
			WIFI_CLIENT_CONNECTION_SUCCESS=false
		fi
	fi
		
	# start ACCESS POINT if needed
	# - if WiFi client mode is disabled and ACCESPOINT mode is enabled
	# - if WiFi client mode is enabled, but failed and ACCESPOINT mode is enabled
	if $WIFI_ACCESSPOINT && ( ! $WIFI_CLIENT_CONNECTION_SUCCESS || ! $WIFI_CLIENT); then
		start_wifi_accesspoint
		
		# check if acces point is up and trigger callback
		# Warning!!! This uses the SSID and isn't tested against hidden SSID configurations
		(
			AP_DOWN=true
			while $AP_DOWN; do
				iw dev | grep -q -E "ssid $WIFI_ACCESSPOINT_NAME"; res=$?
				if [ $res == 0 ]; then 
					AP_DOWN=false

				        if $WIFI_ACCESSPOINT_KARMA && $WIFI_NEXMON; then
						WIFI_enable_KARMA
				        fi
				        if $WIFI_ACCESSPOINT_KARMA_LOUD && $WIFI_NEXMON; then
						WIFI_enable_KARMA_LOUD
				        fi

					declare -f onAccessPointUp > /dev/null && onAccessPointUp # run only once
				fi
			done
		)&
	fi
fi

detect_usb_hostmode # creates OTG_MODE=true if P4wnP1 is in OTG mode

# early out if P4wnP1 is used in OTG mode
if $OTG_MODE; then
	echo "As P4wnP1 is detected to run in Host (interactive) mode, we abort device setup now!"
	exit
else
	echo "P4wnP1: ... USB gadget initialized"
fi

# check if ethernet over USB should be used
if $USB_RNDIS || $USB_ECM; then 
	USB_ETHERNET=true 
fi

# change hostname to make P4wnP1 resolveable on "name.local"
if $WIFI || $USB_ETHERNET; then
	hostname="MAME82-P4WNP1"

	hostname $hostname
	echo $hostname > /etc/hostname

	# add to /etc/hosts
	if ! grep -q -E "^127\.0\.0\.1 $hostname\$" /etc/hosts; then
	        echo "127.0.0.1 $hostname" >> /etc/hosts
	fi
fi



# if ethernet over USB is in use, detect active interface and start DHCP (all as background job)
if $USB_ETHERNET; then
	echo "P4wnP1: Initializing Ethernet over USB..."
	source $wdir/boot/init_usb_ethernet.sh
	(
		detect_active_interface

		if [ "$active_interface" != "none" ]; then 
			create_DHCP_config
			dnsmasq -C /tmp/dnsmasq_usb_eth.conf

			# callback onNetworkUp() of payload script
			declare -f onNetworkUp > /dev/null && onNetworkUp

			# wait for client to receive DHCP lease
			target_ip=""
			while [ "$target_ip" == "" ]; do
				target_ip=$(cat /tmp/dnsmasq.leases | cut -d" " -f3)
				target_name=$(cat /tmp/dnsmasq.leases | awk '{print $4}')
				sleep 0.2
			done

			# callback onNetworkGotIP() of payload script 
			declare -f onTargetGotIP > /dev/null && onTargetGotIP

		fi
	)&
fi

# take care of AutoSSH reachback
source $wdir/boot/init_autossh.sh
start_autossh # start_autossh takes care of checking AUTOSSH_ENABLED

if $USE_HID_MOUSE; then
	# import mouse functions
	source $wdir/boot/init_hid_mouse.sh
	declare -f outmouse >> /tmp/profile.sh
	chown pi:pi /tmp/profile.sh
fi

if $USE_HID; then
	# import keyboard functions
	source $wdir/boot/init_hid_keyboard.sh
	
	declare -f outhid >> /tmp/profile.sh
	declare -f duckhid >> /tmp/profile.sh
	chown pi:pi /tmp/profile.sh

	# if HID keyboard should be tested for readyness, do it (triggers "onKeyboardUp" callback of payload)
	if $HID_KEYBOARD_TEST; then
#		detect_HID_keyboard&

		(
		        echo "Waiting for HID keyboard to be usable..."
			# blocking read of LED status
			python -c "with open('/dev/hidg0','rb') as f:  print ord(f.read(1))"
			# fire 'onKeyboardUp' after read has succeeded
			declare -f onKeyboardUp > /dev/null && onKeyboardUp
		)&
	fi
fi



# trigger callback for on boot finished
#(
#	declare -f onBootFinished > /dev/null && onBootFinished # run only once
#)&
